package com.biz.common.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Repository;

import com.biz.common.dao.GenericDAO;
import com.framework.support.CustomHibernateDaoSupport;

@Repository("genericDAOImpl")
public class GenericDAOImpl<T, PK extends Serializable> extends CustomHibernateDaoSupport implements GenericDAO<T, PK> {
	Log log = LogFactory.getLog(GenericDAOImpl.class);

	@SuppressWarnings("unchecked")
	public PK insert(T entity) throws DataAccessException {
		return (PK) getHibernateTemplate().save(entity);
	}

	public void update(T entity) throws DataAccessException {
		getHibernateTemplate().update(entity);

	}

	public void delete(Class<T> entityClazz, PK id) throws DataAccessException {
		getHibernateTemplate().delete(getHibernateTemplate().get(entityClazz, id));

	}

	@SuppressWarnings("unchecked")
	public T query(Class<T> entityClazz, PK id) throws DataAccessException {
		return (T) getHibernateTemplate().get(entityClazz, id);
	}

	@SuppressWarnings("unchecked")
	public List<T> getAll(Class<T> entityClazz) throws DataAccessException {
		return getHibernateTemplate().loadAll(entityClazz);
	}

	@SuppressWarnings("unchecked")
	public List<T> queryForHQLPaging(final String hql, final int pageNo, final int pageSize) throws DataAccessException {
		List<T> list = getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				List<T> result = session.createQuery(hql).setFirstResult(pageNo).setMaxResults(pageSize).list();
				return result;
			}
		});
		return list;
	}

	@SuppressWarnings("unchecked")
	public List<T> queryForPaging(final DetachedCriteria criteria, final int pageNo, final int pageSize)
			throws DataAccessException {
		return getHibernateTemplate().findByCriteria(criteria, pageNo, pageSize);
	}

	@SuppressWarnings("unchecked")
	public List<T> queryForCriteriaPaging(final Class<T> entityClazz, final Criterion[] criterions, final int pageNo,
			final int pageSize) throws DataAccessException {
		List<T> list = getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Criteria criteria = session.createCriteria(entityClazz);
				for (Criterion criterion : criterions) {
					criteria.add(criterion);
				}
				criteria.setFirstResult(pageNo);
				criteria.setMaxResults(pageSize);
				return criteria.list();
			}
		});
		return list;
	}

}
